home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 2.iso
/
toolbox
/
public
/
figlet
/
figlet2.1.1
/
chkfont.c
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
11KB
|
405 lines
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define DATE "25 Aug 1994"
#define VERSION "2.1.1"
/*
chkfont
By Glenn Chappell <ggc@uiuc.edu>
This program checks figlet 2.0/2.1 font files for format errors.
It also looks for signs of common problems and gives warnings.
chkfont does not modify font files.
Usage: chkfont fontfile ...
Note: This is very much a spare-time project. It's probably
full o' bugs ....
*/
/* #define CHECKBLANKS */
#define FONTFILESUFFIX ".flf"
#define FONTFILEMAGICNUMBER "flf2"
char posshardblanks[9] = { '!', '@', '#', '$', '%', '&', '*', 0x7f, 0 };
char *myname,*fontfilename;
FILE *fontfile;
char hardblank;
int charheight,upheight,maxlen=0,smushmode;
char *fileline;
int maxlinelength=0,currline;
int ec,wc;
int incon_endmarkwarn,endmark_countwarn,nonincrwarn;
int bigcodetagwarn,smallcodetagwarn,deutschcodetagwarn,asciicodetagwarn;
int codetagcnt;
int gone;
weregone(really)
int really;
{
if (!really && 2*ec+wc<=40) {
return;
}
if (ec+wc>0) printf("*******************************************************************************\n");
if (!really) {
printf("%s: Too many errors/warnings.\n",fontfilename);
}
printf("%s: Errors: %d, Warnings: %d\n",fontfilename,ec,wc);
if (currline>1) {
printf("%s: maxlen: %d, actual max line length: %d\n",
fontfilename,maxlen,maxlinelength);
if (codetagcnt>0) {
printf("%s: Code-tagged characters: %d\n",fontfilename,codetagcnt);
}
}
printf("-------------------------------------------------------------------------------\n");
gone=1;
}
char *my_alloc(size)
int size;
{
char *ptr;
ptr=(char *)malloc(size);
if (ptr==NULL) {
fprintf(stderr,"%s: Out of memory\n",myname);
}
else {
return(ptr);
}
}
usageerr()
{
fprintf(stderr,"chkfont by Glenn Chappell <ggc@uiuc.edu>\n");
fprintf(stderr,"Version: %s, date: %s\n",VERSION,DATE);
fprintf(stderr,"Checks figlet 2.0/2.1 font files for format errors.\n");
fprintf(stderr,"(Does not modify font files.)\n");
fprintf(stderr,"Usage: %s fontfile ...\n",myname);
exit(1);
}
readchar()
{
int i,expected_width,k,len,newlen,diff,l;
char endmark,expected_endmark;
int leadblanks,minleadblanks,trailblanks,mintrailblanks;
for (i=0;i<charheight;i++) {
fgets(fileline,maxlen+1000,fontfile);
if (feof(fontfile)) {
printf("%s: ERROR (fatal)- Unexpected end of file after line %d.\n",
fontfilename,currline);
ec++;
weregone(1); if (gone) return;
}
currline++;
len=strlen(fileline)-1;
if (len>maxlinelength) {
maxlinelength=len;
}
if (len>maxlen) {
printf("%s: ERROR- Line length > maxlen in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
k=len;
endmark=k<0?'\0':(k==0||fileline[k]!='\n')?fileline[k]:fileline[k-1];
for(;k>=0?(fileline[k]=='\n' || fileline[k]==endmark):0;k--) {
fileline[k]='\0';
}
newlen=strlen(fileline);
for (l=0;l<newlen ? fileline[l]==' ' : 0;l++) ;
leadblanks = l;
for (l=newlen-1;l>=0 ? fileline[l]==' ' : 0;l--) ;
trailblanks = newlen-1-l;
if (i==0) {
expected_endmark = endmark;
expected_width = newlen;
minleadblanks = leadblanks;
mintrailblanks = trailblanks;
if (endmark==' ') {
printf("%s: Warning- Blank endmark in line %d.\n",
fontfilename,currline);
wc++;
weregone(0); if (gone) return;
}
}
else {
if (leadblanks<minleadblanks) minleadblanks = leadblanks;
if (trailblanks<mintrailblanks) mintrailblanks = trailblanks;
if (endmark!=expected_endmark && !incon_endmarkwarn) {
printf("%s: Warning- Inconsistent endmark in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
incon_endmarkwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (newlen!=expected_width) {
printf("%s: ERROR- Inconsistent character width in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
}
diff=len-newlen;
if (diff>2) {
printf("%s: ERROR- Too many endmarks in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
else if (charheight>1 && (diff!=(i==charheight-1)+1)) {
if (!endmark_countwarn) {
printf("%s: Warning- Endchar count convention violated in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
endmark_countwarn = 1;
wc++;
weregone(0); if (gone) return;
}
}
}
#ifdef CHECKBLANKS
if (minleadblanks+mintrailblanks>0 && smushmode>=0) {
printf("%s: Warning- Leading/trailing blanks in char. ending at line %d.\n",
fontfilename,currline);
printf("%s: (Above warning only given when smushmode > -1.)\n",
fontfilename);
wc++;
weregone(0); if (gone) return;
}
#endif /* #ifdef CHECKBLANKS */
}
checkit()
{
int i,k,cmtcount,numsread,ffrighttoleft;
char magicnum[5],cha;
long oldord,theord;
int tmpcnt,len;
ec=0;wc=0;
incon_endmarkwarn=0; endmark_countwarn=0; nonincrwarn=0;
bigcodetagwarn=0; smallcodetagwarn=0;
deutschcodetagwarn=0; asciicodetagwarn=0;
codetagcnt=0;
gone=0;
if (!strcmp(fontfilename,"-")) {
fontfilename="(stdin)";
fontfile=stdin;
}
else {
fontfile=fopen(fontfilename,"r");
if (fontfile == NULL) {
fprintf(stderr,"%s: Could not open file '%s'\n",myname,fontfilename);
exit(1);
}
}
if (fontfile!=stdin) {
if (strlen(fontfilename)<strlen(FONTFILESUFFIX)?1
:strcmp(fontfilename+strlen(fontfilename)-4,FONTFILESUFFIX)) {
printf("%s: ERROR- Filename does not end with '%s'.\n",
fontfilename,FONTFILESUFFIX);
ec++;
weregone(0); if (gone) return;
}
}
fscanf(fontfile,"%4s",magicnum);
if (strcmp(magicnum,FONTFILEMAGICNUMBER)) {
printf("%s: ERROR- Incorrect magic number.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
cha=getc(fontfile);
if (cha!='a') {
printf("%s: Warning- Sub-version character is not 'a'.\n",fontfilename);
wc++;
weregone(0); if (gone) return;
}
fileline=(char*)my_alloc(sizeof(char)*(1001));
if (fgets(fileline,1001,fontfile)==NULL) {
fileline[0] = '\0';
}
if (strlen(fileline)>0 ? fileline[strlen(fileline)-1]!='\n' : 0) {
while(k=getc(fontfile),k!='\n'&&k!=EOF) ; /* Advance to end of line */
}
numsread=sscanf(fileline,"%c %d %d %d %d %d%*[ ]%d",
&hardblank,&charheight,&upheight,&maxlen,&smushmode,&cmtcount,
&ffrighttoleft);
free(fileline);
if (numsread<7) {
ffrighttoleft=0;
}
if (6>numsread) {
printf("%s: ERROR (fatal)- First line improperly formatted.\n",fontfilename);
ec++;
weregone(1); if (gone) return;
}
if (!strchr(posshardblanks,hardblank)) {
printf("%s: Warning- Unusual hardblank.\n",fontfilename);
wc++;
weregone(0); if (gone) return;
}
if (charheight<1) {
printf("%s: ERROR (fatal)- charheight not positive.\n",fontfilename);
ec++;
weregone(1); if (gone) return;
}
if (upheight>charheight || upheight<1) {
printf("%s: ERROR- up_height out of bounds.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (maxlen<1) {
printf("%s: ERROR (fatal)- maxlen not positive.\n",fontfilename);
ec++;
weregone(1); if (gone) return;
}
if (smushmode<-1) {
printf("%s: ERROR- smushmode < -1.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (smushmode>63) {
printf("%s: Warning- smushmode > 63.\n",fontfilename);
wc++;
weregone(0); if (gone) return;
}
if (cmtcount<0) {
printf("%s: ERROR- cmt_count is negative.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
if (ffrighttoleft<0 || ffrighttoleft>1) {
printf("%s: ERROR- rtol out of bounds.\n",fontfilename);
ec++;
weregone(0); if (gone) return;
}
for (i=1;i<=cmtcount;i++) {
while(k=getc(fontfile),k!='\n'&&k!=EOF) ; /* Advance to end of line */
}
maxlinelength = 0;
currline=cmtcount+1;
fileline=(char*)my_alloc(sizeof(char)*(maxlen+1001));
for (i=0;i<102;i++) {
readchar();
if (gone) return;
}
oldord=0;
while(fgets(fileline,maxlen+1000,fontfile)!=NULL) {
currline++;
len=strlen(fileline)-1;
if (len>maxlinelength) {
maxlinelength=len;
}
if (len>maxlen) {
printf("%s: ERROR- Line length > maxlen in line %d.\n",
fontfilename,currline);
ec++;
weregone(0); if (gone) return;
}
tmpcnt=sscanf(fileline,"%li",&theord);
if (tmpcnt<1) {
printf("%s: Warning- Extra chars after font in line %d.\n",
fontfilename,currline);
wc++;
weregone(0); if (gone) return;
break;
}
codetagcnt++;
if (theord>65535 && !bigcodetagwarn) {
printf("%s: Warning- Code tag > 65535 in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
bigcodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (theord<-255 && !smallcodetagwarn) {
printf("%s: Warning- Code tag < -255 in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
smallcodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (theord<= -249 && theord>= -255 && !deutschcodetagwarn) {
printf("%s: Warning- Code tag in \"Deutsch\" range in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
deutschcodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
if (theord<127 && theord>0 && !asciicodetagwarn) {
printf("%s: Warning- Code tag in ASCII range in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
asciicodetagwarn = 1;
wc++;
weregone(0); if (gone) return;
}
else if (theord<=oldord && theord!=0 && oldord!=0 && !nonincrwarn) {
printf("%s: Warning- Non-increasing code tag in line %d.\n",
fontfilename,currline);
printf("%s: (Above warning will only be printed once.)\n",
fontfilename);
nonincrwarn = 1;
wc++;
weregone(0); if (gone) return;
}
oldord=theord;
readchar();
if (gone) return;
}
if (fontfile!=stdin) fclose(fontfile);
weregone(1); if (gone) return;
}
int main(argc,argv)
int argc;
char *argv[];
{
int arg;
if ((myname=strrchr(argv[0],'/'))!=NULL) {
myname++;
}
else {
myname = argv[0];
}
if (argc<2) {
usageerr();
}
for (arg=1;arg<argc;arg++) {
fontfilename=argv[arg];
fileline=NULL;
checkit();
if (fileline!=NULL) free(fileline);
}
exit(0);
}